﻿using ArtMath.Resource;
using System;
using System.Collections.Generic;
using System.Drawing;
using ArtMath.PointCollection;
using ArtMath.Core.Data;
using ArtMath.Component.Point;
using ArtMath.Core.Helper;
using ArtMath.Helper;
using ArtMath.CommonType;

namespace ArtMath.Component.Circle
{
    /// <summary>
    /// 圆基类
    /// </summary>
    [Serializable]
    public abstract class FullCircleBase : CircleLikeBase
    {
        public FullCircleBase(SketchPad pad, string name, ToolTypeName toolType, bool addToList = true) : base(pad, name, toolType, addToList)
        {
            ske = new PointCollection.Circle() { Curves = new Curve[] { new Curve() { IsClosed = true } } };
            pske = new Ellipse() { Curves = new Curve[] { new Curve() { IsClosed = true } } };
            newCur.IsClosed = newPCur.IsClosed = true;
        }
        public override PointCollectionsManager NewSkeleton
        {
            get
            {
                Pad.BuildCircleSamples(newCur, null, NewCenter, NewRadius);
                return new PointCollectionsManager(new PointCollection.Circle(NewCenter, NewRadius) { Curves = new Curve[] { newCur } });
            }
        }
        public override PointCollectionsManager NewPSkeleton
        {
            get
            {
                Pad.BuildCircleSamples(null, newPCur, NewCenter, NewRadius);
                Ellipse e = new Ellipse() { Center = NewPCenter, Curves = new Curve[] { newPCur } };
                double r = NewRadius;
                if (Pad.Coordinate == null)
                {
                    e.LongAxisHalfLength = e.ShortAxisHalfLength = r;
                }
                else
                {
                    e.LongAxisHalfLength = Pad.Coordinate.GetPx(r);
                    e.ShortAxisHalfLength = Pad.Coordinate.GetPy(r);
                }
                return new PointCollectionsManager(e);
            }
        }
        //public override IList<Curve> NewCurves
        //{
        //    get
        //    {
        //        Pad.BuildCircleSamples(newCur, null, NewCenter, NewRadius);
        //        return base.NewCurves;
        //    }
        //}
        //public override IList<Curve> NewPCurves
        //{
        //    get
        //    {
        //        Pad.BuildCircleSamples(null, newPCur, NewCenter, NewRadius);
        //        return base.NewPCurves;
        //    }
        //}
        public override void AddTracks()
        {
            track.Add(new KeyValuePair<PointD, double[]>(PCenter, new double[] { -Pad.Coordinate.RotateAngle.DegreeValue, pske.LongAxisHalfLength, pske.ShortAxisHalfLength }));
        }
        //protected override PointD GetAbsorbedPoint(PointD PLocation, bool getNew = false)
        //{
        //    if (getNew)
        //    {
        //        return Pad.FixOnCircle(NewPCenter, NewRadius, PLocation);
        //    }
        //    return Pad.FixOnCircle(PCenter, Radius, PLocation);
        //}
        public override PointD GetOutFreePointRecommendNewLocation(PointBase pt, bool getXY = true)
        {
            PointD tmp = NewPCenter;
            tmp = Pad.FixOnCircle(tmp, NewRadius, pt.Pxy + tmp - PCenter);
            return getXY ? Pad.PxyToXY(tmp) : tmp;
        }
        //public override PointD[] GetCrossPoints(ShapeBase shape, bool getNew = true)
        //{
        //    List<PointD> res = new List<PointD>();
        //    PointD[] pts = null;
        //    ThreePointsPartialCircleBase tppcb = shape as ThreePointsPartialCircleBase;
        //    if (tppcb != null)
        //    {
        //        pts = getNew ? CurveIntersection.ArcCircleIntersection(tppcb.NewCenter, tppcb.NewRadius, tppcb.NewStart, tppcb.NewSweep, NewCenter, NewRadius) :
        //             CurveIntersection.ArcCircleIntersection(tppcb.Center, tppcb.Radius, tppcb.Start.RadValue, tppcb.Sweep.RadValue, Center, Radius);
        //        if (Pad.Coordinate != null && pts != null)
        //        {
        //            for (int i = 0; i < pts.Length; i++)
        //            {
        //                pts[i] = Pad.Coordinate.XYToPxy(pts[i]);
        //            }
        //        }
        //    }
        //    else
        //    {
        //        CircleLikeBase clb = shape as CircleLikeBase;
        //        if (clb != null)
        //        {
        //            pts = getNew ? CurveIntersection.CirclesIntersection(NewCenter, NewRadius, clb.NewCenter, clb.NewRadius) :
        //                 CurveIntersection.CirclesIntersection(Center, Radius, clb.Center, clb.Radius);
        //            if (Pad.Coordinate != null && pts != null)
        //            {
        //                for (int i = 0; i < pts.Length; i++)
        //                {
        //                    pts[i] = Pad.Coordinate.XYToPxy(pts[i]);
        //                }
        //            }
        //        }
        //    }
        //    if (pts != null) res.AddRange(pts);
        //    if (res.Count == 0) return null;
        //    return res.ToArray();
        //}
        public override void ComponentBuilding(Base component)
        {
            Circumference = Core.Helper.Angle.RadRound * Radius;
            Area = Math.PI * Radius * Radius;
            AppendStatus($"，{Resources.Translate("CircleCenter")}{Resources.ColonSeparate}{Pad.ShowPoint(Center)}{Resources.CommaSeparate}{Resources.Translate("Radius")} = {Radius}");
            Pad.BuildCircleSamples(ske.Curves[0], pske.Curves[0], Center, Radius);
            base.ComponentBuilding(component);
        }
        public override void ComponentChanged(ShapeBase component)
        {
            base.ComponentChanged(component);
            Circumference = Core.Helper.Angle.RadRound * Radius;
            Area = Math.PI * Radius * Radius;
            Pad.BuildCircleSamples(ske.Curves[0], pske.Curves[0], Center, Radius);
        }
        public override PointD[] GetTangentPoints(PointD passPoint)
        {
            return CurveTangent.GetCircleTangentPoints(NewCenter, NewRadius, passPoint);
        }
        //public override PointD SlideDestination(PointD currentLocation, double length, out bool reverse)
        //{
        //    Circle c = new Circle(NewCenter, NewRadius);
        //    return c.SlideDestination(currentLocation, length, out reverse);
        //}
        public override void Paint(Graphics gra)
        {
            if (ObjectState == ObjectState.Normal && Visible && IsCreationCompleted)
            {
                Brush bru = FillBrush;
                if (bru != null) gra.DrawCircle(LinePen, bru, PCenter, Pad.Coordinate == null ? 0 : -Pad.Coordinate.RotateAngle.DegreeValue, pske.LongAxisHalfLength, pske.ShortAxisHalfLength);
            }
            base.Paint(gra);
        }
        public override void PaintVirtualObjects(Graphics gra)
        {
            if (CanDrawVirtual)
            {
                gra.DrawCircle(PCenter, Pad.Coordinate == null ? 0 : -Pad.Coordinate.RotateAngle.DegreeValue, pske.LongAxisHalfLength, pske.ShortAxisHalfLength);
            }
            base.PaintVirtualObjects(gra);
        }
        public override void PaintTrack(Graphics gra)
        {
            if (ShowTrack_)
            {
                for (int i = 0; i < track.Count; i++)
                {
                    gra.DrawCircle(TrackPen, null, track[i].Key, track[i].Value[0], track[i].Value[1], track[i].Value[2]);
                }
            }
            base.PaintTrack(gra);
        }
    }
}
